package com.eportal.service.impl;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import com.eportal.action.background.CInstallUnitAction;
import com.eportal.dao.TCinstallUnitEntityMapper;
import com.eportal.vo.controller.background.cinstallunit.CInstallUnitSelectListVO;
import com.eportal.vo.controller.background.cinstallunit.ListBudingAndUnitVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eportal.aop.LogAnnotation;
import com.eportal.base.BaseDAO;
import com.eportal.domain.CBuilding;
import com.eportal.domain.CInstallUnit;
import com.eportal.domain.Sysopt;
import com.eportal.domain.TKeys;
import com.eportal.domain.TLock;
import com.eportal.service.CInstallUnitService;
import com.eportal.service.TLocksService;
import com.eportal.util.ValidateUtil;
import com.framework.jqgrid.JqGridPager;

/**
 * 楼栋管理业务逻辑接口实现
 */
@Service("cInstallUnitService")
public class CInstallUnitServiceImpl implements CInstallUnitService {

	private Map<String, Object> result = new HashMap<String, Object>();
	private static Logger log = Logger.getLogger(CInstallUnitServiceImpl.class.getName());
	@Autowired
	private TLocksService tlocksService;
	@Resource(name="dao")
	private BaseDAO dao;

	@Resource
	private TCinstallUnitEntityMapper tCinstallUnitDao;

	@Override
    public List<CInstallUnit> list(String where) {
    	List<CInstallUnit> list= null;
    	if (where == null) {
    		list = dao.query(" from CInstallUnit");
		}else{
			list = dao.query(" from CInstallUnit "+where);
		}
    	return list;
    }

	@Override
	public Map<String, String> getBySql(Long sid) {
		List<Map<String, String>> list= null;
		StringBuilder sql = new StringBuilder("select b.*,t02_agtent.agtname from t10_appstore b left join t02_agtent on b.agtcode=t02_agtent.agtcode  where b.sid=");
		sql.append(sid);
		list= dao.queryBySql(sql.toString());
		if (list.size()>0) {
			return list.get(0);
		}
		return null;
	}

    @Override
    public CInstallUnit add(CInstallUnit cInstallUnit) throws Exception {
    	dao.save(cInstallUnit);
        return cInstallUnit;
    }

    @Override
    public void delete(Long id) {
    	CInstallUnit cInstallUnit = (CInstallUnit) dao.getById(CInstallUnit.class, id);
    	dao.delete(cInstallUnit);
    }

    @Override
    public void delete(List<Long> ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    public CInstallUnit get(Long sid) {
        return (CInstallUnit) dao.getById(CInstallUnit.class, sid);
    }

    public Map<String, String> getCInstallUnit(Long sid) {
    	List<Map<String, String>> list= null;
		StringBuilder sql = new StringBuilder("select T032_CINSTALLUNIT.sid,T032_CINSTALLUNIT.cbname,T032_CINSTALLUNIT.cBuildingId,T031_CBUILDING.cbname as comm from T032_CINSTALLUNIT ,T031_CBUILDING where T032_CINSTALLUNIT.cbuildingid=T031_CBUILDING.sid and T032_CINSTALLUNIT.sid =");
		sql.append(sid);
		list= dao.queryBySql(sql.toString());
		if (list.size()>0) {
			return list.get(0);
		}
		return null;
    }

    @Override
    public void update(CInstallUnit cInstallUnit) throws Exception {

        dao.update(cInstallUnit);
    }

    public void updateObject(Object entity) throws Exception {
    	dao.update(entity);
	}

    @Override
	public List<Map<String, Object>> queryBySql(String communityId) {
		StringBuffer sql = new StringBuffer();
		sql.append("select t.sid,t.cbName,u.usid,uc.userids,uc.usertel,uc.username from t031_cbuilding t "
				+ "left join "
					+ "(select u.cBuildingId,XMLAGG(XMLELEMENT(E, u.sid||'|'|| u.cbName || ',') order by u.sid).EXTRACT('//text()').getclobval() as usid "
					+ "from t032_cinstallunit u group by u.cBuildingId )"
				+ " u "
				+ "on t.sid=u.cBuildingId "
				+ "left join "
					+ "(select uc.cbuildingid,XMLAGG(XMLELEMENT(E, uc.userid || ',')).EXTRACT('//text()').getclobval() as userids,"
					+ "XMLAGG(XMLELEMENT(E, u.tel || ',')).EXTRACT('//text()').getclobval() as usertel,"
					+ "XMLAGG(XMLELEMENT(E, u.auname || ',')).EXTRACT('//text()').getclobval() as username "
					+ "from t04_users_community uc  left join t04_users u on uc.userid=u.userid group by uc.cbuildingid ) "
				+ "uc "
				+ "on uc.cbuildingid=t.sid "
				+ "where t.communityid=");
		sql.append(communityId);
		return dao.queryBySql(sql.toString());
	}
	 /**
     * 安装点修改保存方法
     */
	@Override
    @LogAnnotation(operateDescribe="安装点修改")
    public Map<String, Object> updateMethod(CInstallUnit cInstallUnit) {
		try {
	        String msg = ValidateUtil.validate(cInstallUnit);
	        result.put("objectId", cInstallUnit.getSid());
	        if (msg == null || msg.trim().length() == 0) {
	        	CBuilding cBuilding = getCBuilding(Long.parseLong(cInstallUnit.getcBuildingId()));
	        	List<Map<String, Object>> listBuilding = getcBuilding(cBuilding.getCommunityId(),cInstallUnit.getComm());
	        	if (listBuilding.size()>0 && !cInstallUnit.getComm().equals(cBuilding.getCbName())) {//存在，但是不是自己的。不能提供修改
	        			result.put("code", 0);
	        			result.put("msg", "该楼栋名称已存在，请修改后保存");
	        			return result;
				}
	        	cBuilding.setCbName(cInstallUnit.getComm());
	        	updateCBuilding(cBuilding);

	        	CInstallUnit entity = get(cInstallUnit.getSid());
	        	List<Map<String, Object>> listUnit = getUnit(cInstallUnit.getcBuildingId(), cInstallUnit.getCbName());
	        	if (listUnit.size()>0 && !entity.getCbName().equals(cInstallUnit.getCbName())) {//存在，但是不是自己的。不能提供修改
	        		 result.put("code", 0);
			         result.put("msg", "该楼栋下单元名称已存在，请修改后保存");
			         return result;
				}
            	entity.setCbName(cInstallUnit.getCbName());
                update(entity);
                result.put("code", 1);
                result.put("msg", "操作成功");
	        } else {
	            result.put("code", 0);
	            result.put("msg", msg);
	        }
		} catch (Exception e) {
			log.error("安装点更新失败", e);
			result.put("code", 0);
			result.put("msg", "操作失败");
		}
        return result;
    }

	/**
	 * 根据 communityId，和楼栋名称查询
	 * @param communityId
	 * @param cbname
	 * @return
	 */
	private List<Map<String, Object>> getcBuilding(String communityId, String cbname) {
		StringBuilder sql = new StringBuilder("select t.cbname,t.sid from T031_CBUILDING t where t.communityid ='");
		sql.append(communityId);
		sql.append("' and t.cbname ='");
		sql.append(cbname);
		sql.append("'");
		return dao.queryBySql(sql.toString());
	}

	/**
	 * 根据 楼栋id，和单元名称查询
	 * @param communityId
	 * @param cbname
	 * @return
	 */
	private List<Map<String, Object>> getUnit(String cbuildingid, String unitName) {
		StringBuilder sql = new StringBuilder("select * from T032_CINSTALLUNIT t where t.cBuildingId='");
		sql.append(cbuildingid);
		sql.append("' and t.cbName ='");
		sql.append(unitName);
		sql.append("'");
		return dao.queryBySql(sql.toString());
	}
	private void updateCBuilding(CBuilding cBuilding) throws Exception {
        dao.update(cBuilding);
    }
	public Object getObjectHql(String name,String where) {
		StringBuffer sb = new StringBuffer("from ");
		sb.append(name);
		sb.append(" where ");
		sb.append(where);
	     return  dao.loadObject(sb.toString());
	}

	public List<TKeys> listByTKeysHql(String hql) {
		return dao.query(hql);
	}

	private CBuilding getCBuilding(long sid) {
		return (CBuilding) dao.getById(CBuilding.class, sid);
	}

	@Override
	/**
     * 单元删除方法,主要用于切面记录操作日志
     */
    @LogAnnotation(operateDescribe="单元删除")
    public Map<String, Object> deleteMethod(String param_ids) {
        try {
            List<Long> ids = new LinkedList<Long>();
            result.put("objectId", param_ids);
            for (String s : param_ids.split(",")) {
            	StringBuffer sb = new StringBuffer(" installunitId ='");
            	sb.append(s);
            	sb.append("'");
            	TLock tLock =tlocksService.getHql(sb.toString());

            	if(tLock ==null && haveRole(s)){
            		ids.add(Long.parseLong(s));
            		delete(Long.parseLong(s));
            	}
            }
            if(ids.size() == 0){
            	result.put("msg", "操作失败，单元已绑定到硬件无法删除");
            }else if(ids.size() !=param_ids.split(",").length){
            	result.put("msg", "操作成功，部分单元已绑定到硬件的无法删除");
            }else{
            	result.put("msg", "操作成功");
            }
            result.put("code", 1);
        } catch (Exception e) {
            log.error("单元删除失败", e);
            result.put("code", 0);
            result.put("msg", "操作失败");
        }
        return result;
    }
	private boolean haveRole(String sid) {
		int userRole =  (Integer) getSession().getAttribute("userRole");
		List<Map<String, Object>> list= null;
		StringBuilder sql = new StringBuilder("select c.sid,c.agtcode from t032_cinstallunit u left join t031_cbuilding b on u.cbuildingid=b.sid left join t03_community c on b.communityid=c.sid where u.sid=");
		sql.append(sid);
		list= dao.queryBySql(sql.toString());
		Map<String, Object> unitmap = null;
		if (list.size()>0) {
			unitmap = list.get(0);
		}else{
			return true;
		}
		Sysopt  user= (Sysopt)getSession().getAttribute("user");
		switch (userRole) {
		case 1:
		case 2:
			return true;
		case 3:
		case 4:
			if (unitmap.get("agtcode") == null || user.getAgtCode().equals(unitmap.get("agtcode").toString())) {
				return true;
			}else{
				return true;
			}
		case 5:
		case 6:
			if (unitmap.get("sid") == null || user.getCommunityId().equals(unitmap.get("sid").toString())) {
				return true;
			}else{
				return true;
			}
		default:
			return false;
		}
	}

	public HttpSession getSession() {
        return ServletActionContext.getRequest().getSession();
    }

	@Override
	public List<CInstallUnit> list(JqGridPager jqGridPager, String communityId) {
		Sysopt  user= (Sysopt)getSession().getAttribute("user");
		StringBuilder sql = new StringBuilder("select T032_CINSTALLUNIT.sid,T032_CINSTALLUNIT.cbname,T031_CBUILDING.cbname as comm from T032_CINSTALLUNIT ,T031_CBUILDING where T032_CINSTALLUNIT.cbuildingid=T031_CBUILDING.sid and T031_CBUILDING.communityId ='");
		sql.append(communityId);
		sql.append("'");

		return dao.query(sql.toString(), jqGridPager);
	}

	@Override
	public List<Map<String, String>> listBySql(String hql) {
		return dao.queryBySql(hql);
	}

	@Override
	@LogAnnotation(operateDescribe="单元新增")
	public Map<String, Object> addMethod(CInstallUnit cInstallUnit) {
		try {
			Sysopt  user= (Sysopt)getSession().getAttribute("user");
			List<Map<String, Object>> listUnit = getUnit(cInstallUnit.getcBuildingId(), cInstallUnit.getCbName());
        	if (listUnit.size()>0) {
        		 result.put("code", 0);
		         result.put("msg", "该楼栋下单元名称已存在，请修改后保存");
		         return result;
			}
			cInstallUnit.setcUserName(Long.toString(user.getSid()));
			cInstallUnit.setcTime(new Timestamp(System.currentTimeMillis()));
			cInstallUnit =  add(cInstallUnit);
            result.put("code", 1);
            result.put("msg", "操作成功");
            result.put("objectId", cInstallUnit.getSid());
		} catch (Exception e) {
			log.error("单元新增保存失败", e);
			result.put("code", 0);
			result.put("msg", "操作失败");
		}
        return result;
	}

	@Override
	public void dateteUselessBuild() {
		 //删除数据库中多余的楼栋数据,房间数据
		try {
			String sqldeleteBuilding = "delete from t031_cbuilding c where c.sid in (select b.sid from t032_cinstallunit i right join t031_cbuilding b on  i.cbuildingid=b.sid where i.sid is null)";
	        dao.excute(sqldeleteBuilding);
	        String sqldeleteRoom = "delete from T035_ROOM tr where tr.sid in (select r.sid from  T035_ROOM r left join t032_cinstallunit u on r.unit_id=u.sid where u.sid is null)";
	        dao.excute(sqldeleteRoom);
		} catch (Exception e) {
			log.error("删除数据库中多余的楼栋和房间数据失败", e);
		}
	}


//todo ---------------------------------------------------------------------------------------------------


	/**
	 * 单元下拉列表
	 *
	 * @param cbuildingId 楼栋id
	 * @param user        当前用户
	 * @param userRole    当前用户userRole
	 * @return
	 * @author Saber
	 * @Date 2017/8/10 上午9:46
	 */
	@Override
	public List<CInstallUnitSelectListVO> selectList(String cbuildingId, Sysopt user, int userRole) {

		if(StringUtils.isEmpty(cbuildingId)){
			return null;
		}
		return tCinstallUnitDao.selectList(cbuildingId,user,userRole);
	}

	/**
	 * 所有的楼栋单元列表
	 *
	 * @param communityId 小区id
	 * @param user        当前用户
	 * @param userRole    当前用户userRole
	 * @return
	 * @author Saber
	 * @Date 2017/8/22 下午5:08
	 * @see CInstallUnitServiceImpl#queryBySql(String)
	 */
	@Override
	public List<ListBudingAndUnitVO> listBudingAndUnit(String communityId, Sysopt user, int userRole) {
		if (org.apache.commons.lang.StringUtils.isBlank(communityId)) {
			communityId = user.getCommunityId();
		}
		return tCinstallUnitDao.listBudingAndUnit(communityId);
	}
}
